package com.citcc.api.utils;

import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradeAppPayModel;
import com.alipay.api.request.AlipayTradeAppPayRequest;
import com.alipay.api.response.AlipayTradeAppPayResponse;
import com.citcc.business.bean.dto.PayDTO;
import com.citcc.business.bean.dto.PaymentDTO;
import com.citcc.business.bean.vo.PaymentVO;
import com.citcc.business.util.IdGenerator;
import org.apache.commons.collections4.map.HashedMap;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.net.URLEncoder;
import java.text.DecimalFormat;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;

/**
 * Created by czh on 2019/5/21 10:07
 */
@Component
public class PaymentServiceUtil {

    @Value("${pay.zhifubao.apppay.appid}")
    private String appId;
    @Value("${pay.zhifubao.apppay.privateKey}")
    private String privateKey;
    @Value("${pay.zhifubao.apppay.publicKey}")
    private String publicKey;
    @Value("${pay.zhifubao.apppay.requesturl}")
    private String requestUrl;
    @Value("${pay.zhifubao.apppay.notifyurl}")
    private String returnUrl;
    @Value("${pay.zhifubao.apppay.partnerid}")
    private String partnerId;
    @Value("${pay.weixin.apppay.appid}")
    private String wxappId;
    @Value("${pay.weixin.apppay.partner}")
    private String mchId;
    @Value("${pay.weixin.apppay.notifyurl}")
    private String wxNotifyUrl;
    private String timeMillis = String.valueOf(System.currentTimeMillis() / 1000);

    /**
     * 充值
     *
     * @param request
     * @param paymentVO
     * @return
     */
    public PaymentDTO recharge(HttpServletRequest request, PaymentVO paymentVO) {

        PaymentDTO paymentDTO = new PaymentDTO();

        try {
            PayDTO payDTO = new PayDTO();
            // 支付类型
            String tradeType = paymentVO.getTradeType();

            switch (tradeType) {
                case "wx-app-pay":
                    payDTO.setPaymoney(paymentVO.getPayMoney());
                    payDTO.setOut_trade_no(paymentVO.getOutTradeNo());
                    payDTO.setAppid(wxappId);
                    payDTO.setMch_id(mchId);
                    payDTO.setUserId(paymentVO.getUserId());
                    payDTO.setDescription(paymentVO.getDescription());
                    payDTO.setWxnotifyURL(wxNotifyUrl);
                    payDTO.setReward(tradeType);
                    paymentDTO.setResult(wxResponseParams(request, payDTO));
                    paymentDTO.setPayState(true);
                    break;
                case "zfb-app-pay":
                    payDTO.setPaymoney(paymentVO.getPayMoney());
                    payDTO.setOut_trade_no(paymentVO.getOutTradeNo());
                    payDTO.setReward(tradeType);
                    payDTO.setUserId(paymentVO.getUserId());
                    payDTO.setDescription(paymentVO.getDescription());
                    paymentDTO.setResult(zfbwxResponseParams(payDTO));
                    paymentDTO.setPayState(true);
                    break;
                default:
            }
        } catch (Exception e) {
            paymentDTO.setPayState(false);
        }

        return paymentDTO;
    }

    /**
     * 封装微信支付响应参数
     *
     * @param request
     * @param payDTO
     * @return
     */
    private SortedMap<String, Object> wxResponseParams(HttpServletRequest request, PayDTO payDTO) {
        Map<String, String> attachmap = new HashedMap<>();
        attachmap.put("userId", payDTO.getUserId());
        attachmap.put("reward", payDTO.getReward());
        Map<String, String> map = PaySystemUtil.WeiXinPrePay(payDTO, request, JSONObject.toJSONString(attachmap));
        SortedMap<String, Object> finalpackage = new TreeMap<>();
        finalpackage.put("appid", payDTO.getAppid());
        finalpackage.put("timestamp", timeMillis);
        finalpackage.put("noncestr", IdGenerator.generateId());
        finalpackage.put("package", "Sign=WXPay");
        finalpackage.put("partnerid", payDTO.getMch_id());
        finalpackage.put("prepayid", map.get("prepay_id"));
        String sign = WeiXinPayUtil.createSign("UTF-8", finalpackage);
        finalpackage.put("paySign", sign);
        return finalpackage;
    }

    /**
     * 封装支付宝支付响应参数
     *
     * @param payDTO
     * @return
     * @throws Exception
     */
    private Map<String, Object> zfbwxResponseParams(PayDTO payDTO) throws Exception {
        Map<String, Object> resultMap = new HashedMap<>();
        DecimalFormat FORMAT = new DecimalFormat("0.00");

        // 公共参数
        Map<String, String> bizModel = new LinkedHashMap<>();
        // 1.商户appId
        bizModel.put("app_id", appId);
        // 2.请求网关地址
        bizModel.put("method", requestUrl);
        // 3.请求格式
        bizModel.put("format", "json");
        // 4.回调地址
        bizModel.put("return_url", returnUrl);
        // 5.私钥
        bizModel.put("private_key", privateKey);
        // 6.商家id
        bizModel.put("seller_id", partnerId);
        // 7.加密格式
        bizModel.put("sign_type", "RSA2");

        // 实例化客户端
        AlipayClient client = new DefaultAlipayClient(requestUrl, appId, privateKey, "json", "UTF-8", publicKey, "RSA2");

        //实例化具体API对应的request类，类名称和接口名称对应，当前调用接口名称：alipay.trade.app.pay
        AlipayTradeAppPayRequest ali_request = new AlipayTradeAppPayRequest();

        //SDK已经封装掉了公共参数，这里只需要传入业务参数。以下方法为sdk的model入参方式(model和biz_content同时存在的情况下取biz_content)
        AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
        model.setPassbackParams(URLEncoder.encode(payDTO.getDescription()));
        //商品描述信息
        model.setBody(payDTO.getDescription());
        // 商品名称
        model.setSubject("新能源车充电");
        // 商户订单号
        model.setOutTradeNo(payDTO.getOut_trade_no());
        // 交易超时时间
        model.setTimeoutExpress("30m");
        // 支付金额
        model.setTotalAmount(FORMAT.format(payDTO.getPaymoney()));
        // 销售产品码
        model.setProductCode("QUICK_WAP_PAY");
        // partnerId
        model.setSellerId(partnerId);
        //商家ID
        model.setPassbackParams(payDTO.getReward() + "_" + URLEncoder.encode(payDTO.getUserId(), "utf-8"));
        model.setGoodsType("1");

        ali_request.setBizModel(model);
        ali_request.setNotifyUrl(returnUrl);

        AlipayTradeAppPayResponse response = client.sdkExecute(ali_request);
        resultMap.put("result", response.getBody());
        return resultMap;
    }
}